<template>
  <div class="im">
    <div class="im_head">
      <p class="title">{{this.$t('index.im_inline')}}</p>
      <p class="close_im" @click="handleCloseChat"></p>
    </div>
    <div class="pd_box" v-if="isPaidui">
      <span>{{paiduiData.msg}}</span>
    </div>
    <div class="im_btn" @click="btn_click">
      {{btn_type==1?$t('index.im_serve'):(btn_type==2?$t('index.im_over'):$t('index.im_over_wait'))}}
    </div>
    <div class="im_msg" ref="common_chat_main">
      <div v-for="(it,i) in msg" :key="i" :class="it.auth==1?'kf_box':(it.auth==2?'fk_box':(it.auth==3?'kf_box':''))">
        <!-- 客服 -->
        <template v-if="it.auth==1">
          <img src="../../assets/kf.png" width="40" height="40" alt="kf">
          <div class="msg_box">
            <template v-if="it.type==2">
              <img :src="it.msg" alt="" width="80px">
            </template>
            <template v-else>{{it.msg}}</template>
          </div>
        </template>
        <!-- 访客 -->
        <template v-else-if="it.auth==2">
          <div class="msg_box">
            <template v-if="it.type==2">
              <img :src="it.msg" alt="" width="80px">
            </template>
            <template v-else>{{it.msg}}</template>
          </div>
          <img src="../../assets/kf2.png" width="40" height="40" alt="kf">
        </template>
        <!-- 问题 -->
        <template v-else-if="it.auth==3">
          <img src="../../assets/kf.png" width="40" height="40" alt="kf">
          <div class="msg_box3">
            <div class="title" v-if="!it.isTrue">{{$t('index.problem')}}</div>
            <ul class="msg_box3_ul">
              <li v-for="(d,ii) in it.data" :key="ii" @click="liClick(d)">
                {{d.title}}
              </li>
            </ul>
          </div>
        </template>
        <!-- 系统 -->
        <template v-else class="system_message">
          <span>{{it.msg}}</span>
        </template>
      </div>
    </div>
    <div class="im_fotter">
      <div class="im_fotter_head">
        <el-upload class="avatar-uploader" action="" :auto-upload="false" :on-change="beforeUpload" :show-file-list="false">
          <img src="../../assets/photo.png" width="28" height="28" alt="">
        </el-upload>
      </div>
      <div class="input-wrapper">
        <div maxlength="500" class="inputContent common_chat_emoji-wrapper-global" id="common_chat_input" contenteditable="true" @paste.stop="inputContent_paste" @drop="inputContent_drop" @keydown="inputContent_keydown"
          @mouseup="inputContent_mouseup" @mouseleave="inputContent_mouseup"></div>
      </div>
    </div>

  </div>

</template>

<script>
import aes from "@/utils/aes";
import rsa from "@/utils/rsa";
import {
  sendMessage,
  question_find,
  service_log_find,
  auth_status,
  auth_close
} from "@/api/im";
export default {
  data() {
    return {
      // open: false,
      path: "ws://192.168.2.15:7720/ws/service",
      socket: "",
      va: "",
      msg: [],
      interval: "",
      num: 0,
      type: 1, //1,还没连上websocket，2连上websocket
      listQuery: {
        pageNum: 1,
        pageSize: 10,
        userId: this.$store.getters.uid,
      },
      total: 0,
      scrollTop: 0,
      loading: true,
      // 排队
      isPaidui: false,
      paiduiData: {
        addTime: "2021-05-24 10:09:21",
        auth: 5,
        expire: 2,
        language: this.$store.getters.lang,
        msg: "您前面有0人在排队",
        type: 3,
        userName: 5,
      },
      // 按钮
      btn_type: 1, // 1人工客服，2结束会话，3结束排队
    };
  },
  mounted() {
    // 初始化
    this.$refs.common_chat_main.addEventListener("scroll", this.Scroll);
    this.service_log_find_fun();
    this.auth_status_fun()
  },
  methods: {
    auth_status_fun() {
      var that = this;
      auth_status().then(res => {
        var data = {};
        if (res.code == 1) {
          that.btn_type = 1;
          data.auth = 3;
          data.data = res.data;
          setTimeout(function(){
            that.$refs.common_chat_main.scrollTop = that.$refs.common_chat_main.scrollHeight;
          },100)
        } else if (res.code == 505) {
          that.btn_type = 2;
          var socketData = this.commonData();
          that.num = 0;
          that.init(socketData.key, socketData.authToken);
        } else {
          // 排队
          that.btn_type = 3;
          // that.isPaidui = true;
          // data.msg = `您前面有${res.data}位在排队`
          // that.paiduiData = data;
          var socketData = this.commonData();
          that.num = 0;
          that.init(socketData.key, socketData.authToken);
        }
        that.msg.push(data);

      })
    },
    handleCloseChat() {
      this.$emit('close', true)
    },
    Scroll(e) {
      var size = this.$refs.common_chat_main.scrollTop;
      if (
        size < 1 &&
        this.total > this.listQuery.pageNum * this.listQuery.pageSize &&
        this.loading
      ) {
        this.service_log_find_fun();
      }
    },
    // 获取聊天记录
    service_log_find_fun() {
      var that = this;
      this.loading = false;
      service_log_find(this.listQuery).then((res) => {
        if (res.code == 1) {
          var arr = [];
          res.data.list.forEach((it) => {
            var obj = {
              auth: it.sender == 1 ? 2 : 1,
              type: it.type ? it.type : 1,
              msg: it.content,
            };
            if (it.type == 5) {
                          obj.auth = 3;
                          obj.isTrue = true;
                          obj.data = JSON.parse(it.content)
                        }
            that.msg.unshift(obj);
          });
          if (that.listQuery.pageNum == 1) {
            setTimeout(function () {
              that.$refs.common_chat_main.scrollTop =
                that.$refs.common_chat_main.scrollHeight;
            }, 100);
          } else {
            that.$refs.common_chat_main.scrollTop =
              that.$refs.common_chat_main.scrollHeight - that.scrollTop;
          }
          that.listQuery.pageNum++;
          that.total = res.data.total;
          that.scrollTop = that.$refs.common_chat_main.scrollHeight;
          setTimeout(function () {
            that.loading = true;
          }, 500);
        }
      });
    },
    init: function (key, authToken) {
      if (typeof WebSocket === "undefined") {
        alert("您的浏览器不支持socket");
      } else {
        // 实例化socket
        this.socket = new WebSocket(
          this.path + `?authToken=${authToken}&key=${key}&platform=2&lang=${this.$store.getters.lang}`
        );
        // 监听socket连接
        this.socket.onopen = this.open;
        // 监听socket错误信息
        this.socket.onerror = this.error;
        // 监听socket消息
        this.socket.onmessage = this.getMessage;
        this.socket.onclose = this.close;
      }
    },
    liClick(row) {
      var that = this;
      this.msg.push({
        auth: 2,
        msg: row.title
      });
      this.msg.push({
        auth: 1,
        msg: row.content
      });
      setTimeout(function () {
        that.$refs.common_chat_main.scrollTop =
          that.$refs.common_chat_main.scrollHeight;
      }, 100);
    },
    open: function () {
      var that = this;
      that.type = 2;
      this.interval = setInterval(function () {
        that.send("ping");
      }, 5000);
    },
    error: function () {
    },
    getMessage: function (msg) {
      var that = this;
      var data = JSON.parse(msg.data);
      if (data.expire == 0) {
        that.btn_type = 1;
        data.auth = 1;
        that.msg.push(data);
        setTimeout(function () {
          that.$refs.common_chat_main.scrollTop =
            that.$refs.common_chat_main.scrollHeight;
        }, 100);
        clearInterval(that.interval);
        that.num = 4;
        return false;
      }
      if (data.type == 1 || data.type == 2) {
        data.auth = 1;
      } else if (data.type == 3 || data.type == 6) {
        // 排队
        that.btn_type = 3;
        that.isPaidui = true;
        that.paiduiData = data;
        return false;
      } else if (data.type == 4) {
        data.auth = 6; // 提示
      } else {
        data.auth = 3;
      }
      that.btn_type = 2;
      that.isPaidui = false;
      that.msg.push(data);
      setTimeout(function () {
        that.$refs.common_chat_main.scrollTop =
          that.$refs.common_chat_main.scrollHeight;
      }, 100);
    },
    send: function (params) {
      this.socket.send(params);
    },
    close: function () {
      var that = this;
      this.socket = "";
      this.type = 1;
      clearInterval(this.interval);
      this.btn_type = 1
      this.msg.push({ auth: 1, msg: "与客服断开连接" });
      setTimeout(function(){
        that.$refs.common_chat_main.scrollTop = that.$refs.common_chat_main.scrollHeight;
      },100)
      // if (this.num < 3) {
      //   var data = this.commonData();
      //   this.num++;
      //   this.init(data.key, data.authToken);
      // }
    },
    commonData(string, data) {
      var string = aes.randomString(16);
      var data = {
        key: rsa.RSAencrypt(string),
        authToken: aes.Encrypt(
          this.$store.getters.token + new Date().getTime(),
          string
        ),
        // authToken: aes.Encrypt(1, string),
      };
      data.key = this.delStr(data.key);
      data.authToken = this.delStr(data.authToken);
      return data;
    },
    delStr(str) {
      str = str
        .replace(/\+/g, "..a,,")
        .replace(/\//g, "..b,,")
        .replace(/\?/g, "..c,,")
        .replace(/\%/g, "..d,,")
        .replace(/\#/g, "..e,,")
        .replace(/\&/g, "..f,,")
        .replace(/\=/g, "..g,,");
      return str;
    },
    sendMsg() {
      var that = this;
      if (that.type == 1 || that.btn_type == 3) {
        var parms = {
          language: this.$store.getters.lang,
          title: this.va,
        };
        that.msg.push({
          type: 1,
          msg: this.va,
          auth: 2
        });
        document.getElementById("common_chat_input").innerHTML = "";
        if (that.va == "人工客服") {
          var socketData = this.commonData();
          that.num = 0;
          that.init(socketData.key, socketData.authToken);
          return false;
        }
        question_find(parms).then((res) => {
          if (res.code == 1) {
            that.msg.push({
              auth: 3,
              data: res.data
            });
            setTimeout(function () {
              that.$refs.common_chat_main.scrollTop =
                that.$refs.common_chat_main.scrollHeight;
            }, 100);
          } else {
            if (res.code == 501) {
              var data = {
                type: 1,
                msg: res.msg,
                auth: 1
              };
              that.msg.push(data);
              setTimeout(function () {
                that.$refs.common_chat_main.scrollTop =
                  that.$refs.common_chat_main.scrollHeight;
              }, 100);
            }
          }
        });
      } else {
        var parms = {
          type: 1,
          msg: this.va,
        };
        sendMessage(parms).then((res) => {
          if (res.code == 1) {
            parms.auth = 2;
            document.getElementById("common_chat_input").innerHTML = "";
            this.msg.push(parms);
            setTimeout(function () {
              that.$refs.common_chat_main.scrollTop =
                that.$refs.common_chat_main.scrollHeight;
            }, 100);
          } else { }
        });
      }
    },
    /**
     * 设置输入内容
     * 根据input输入框innerHTML转换为纯文本
     */
    setInputContentByDiv: function () {
      var self = this;
      var htmlStr = document.getElementById("common_chat_input").innerHTML;

      // 1.转换表情为纯文本：<img textanme="[笑]"/> => [笑]
      var tmpInputContent = htmlStr
        .replace(/<img .+?text=\"(.+?)\".+?>/g, "[$1]")
        .replace(/<.+?>/g, "");

      // 2.设置最长长度
      if (tmpInputContent.length > 500) {
        document.getElementById("common_chat_input").innerHTML = "";
        var value = tmpInputContent
          .substr(0, 499)
          .replace(/\[(.+?)\]/g, function (item, value) {
            return self.$refs.qqemoji.getImgByFaceName(value);
          });
        this.setInputDiv(value);
      }

      // 3.修改store
      this.va = tmpInputContent;
    },
    inputContent_keydown: function (e) {
      // keyup触发时，绑定的数据还没有被变更，需要进行延后访问
      clearTimeout(this.$data.inputContent_setTimeout);
      this.$data.inputContent_setTimeout = setTimeout(() => {
        this.setInputContentByDiv();

        // 若按了回车，直接发送
        if (e.keyCode == 13) {
          this.sendMsg();
        }
        this.setInputContentSelectRange();
      }, 1);
    },
    /**
     * 输入框的mouseup
     */
    inputContent_mouseup: function (e) {
      this.setInputContentSelectRange();
    },
    /**
     * 设置input输入框的选择焦点
     */
    setInputContentSelectRange: function () {
      if (window.getSelection && window.getSelection().rangeCount > 0) {
        var selectRange = window.getSelection().getRangeAt(0);
        if (
          selectRange.commonAncestorContainer.nodeName == "#text" &&
          selectRange.commonAncestorContainer.parentElement &&
          selectRange.commonAncestorContainer.parentElement.id ==
          "common_chat_input"
        ) {
          // 选中了输入框内的文本
          this.$data.selectionRange = selectRange;
        } else if (
          selectRange.commonAncestorContainer.id == "common_chat_input"
        ) {
          // 选中了输入框
          this.$data.selectionRange = selectRange;
        }
      }
    },
    beforeUpload(file, fileList, index) {
      this.uploadFun(file);
    },
    uploadFun(file) {
      var that = this;
      const fil = {
        file: file.raw,
        fileRename: new Date().getTime(),
      };
      const upload = new UCloudUFile();
      upload.uploadFile(
        fil,
        (res) => {
          sendMessage({
            type: 2,
            msg: `${res.url}${res.name}`,
          }).then((res1) => {
            if (res1.code == 1) {
              var parms = {
                type: 2,
                msg: `${res.url}${res.name}`,
              };
              parms.auth = 2;
              that.msg.push(parms);
              setTimeout(function () {
                that.$refs.common_chat_main.scrollTop =
                  that.$refs.common_chat_main.scrollHeight;
              }, 100);
            }
          });
        },
        (err) => {
          ////console.log(err);
        },
        (progress) => {
          ////console.log(progress);
        }
      );
    },
    /**
     * 输入框的拖拽
     */
    inputContent_drop: function (e) {
      var self = this;
      setTimeout(function () {
        self.setInputContentByDiv();
      }, 100);
    },
    /**
     * 输入框的粘贴
     */
    inputContent_paste: function (e) {
      var self = this;
      var isImage = false;
      if (e.clipboardData && e.clipboardData.items.length > 0) {
        // 1.上传图片
        for (var i = 0; i < e.clipboardData.items.length; i++) {
          var item = e.clipboardData.items[i];
          if (item.kind == "file" && item.type.indexOf("image") >= 0) {
            // 粘贴板为图片类型
            var file = item.getAsFile();
            self.uploadFun(file);
            isImage = true;
          }
        }

        // 2.非图片，粘贴纯文本
        if (!isImage) {
          var str = e.clipboardData.getData("text/plain");
          // 转化为纯文字
          self.va = str;
          var span = document.createElement("span");
          span.innerHTML = str;
          var txt = span.innerText;
          this.setInputDiv(
            txt
              .replace(/\n/g, "")
              .replace(/\r/g, "")
              .replace(/</g, "&lt;")
              .replace(/>/g, "&gt;")
          );
        }
      }
      e.stopPropagation();
      e.preventDefault();
    },
    setInputDiv: function (value) {
      if (this.$data.selectionRange == null) {
        document.getElementById("common_chat_input").focus();
        return;
      }
      // 1.设置selectionRange
      if (window.getSelection) {
        window.getSelection().removeAllRanges();
        window.getSelection().addRange(this.$data.selectionRange);
      } else {
        this.$data.selectionRange && this.$data.selectionRange.select();
      }

      // 2.表情转换为img

      // 3.聊天框中是否选中了文本，若选中文本将被替换成输入内容
      if (window.getSelection) {
        var sel, range;
        // IE9 and non-IE
        sel = window.getSelection();
        if (sel.getRangeAt && sel.rangeCount) {
          // 1)删除选中的文本(内容)
          range = sel.getRangeAt(0); // 获取鼠标选中的文本区域
          range.deleteContents(); // 删除选中的文本

          // 2)创建以输入内容为内容的DocumentFragment
          var elemnet;
          if (range.createContextualFragment) {
            elemnet = range.createContextualFragment(value);
          } else {
            // 以下代码等同createContextualFragment
            // 创建一个DocumentFragment
            elemnet = document.createDocumentFragment();

            var divEl = document.createElement("div");
            divEl.innerHTML = value;
            // divEl下的元素，依次插入到DocumentFragment
            for (let i = 0, len = divEl.children.length; i < len; i++) {
              elemnet.appendChild(divEl.firstChild);
            }
          }
          // 3)选中文本的位置替换为新输入的内容，并把光标定位到新内容后方
          var lastNode = elemnet.lastChild;
          range.insertNode(elemnet);
          range.setStartAfter(lastNode);
          sel.removeAllRanges();
          sel.addRange(range);
        }
      } else if (document.selection && document.selection.type != "Control") {
        // IE < 9
        document.selection.createRange().pasteHTML(imgStr);
      }

      // 4.修改inputContent
      this.setInputContentByDiv();
    },
    // 按钮
    btn_click() {
      var that = this;
      if (this.socket) {
        auth_close().then(res => {
          that.socket = "";
          that.type = 1;
          that.num = 3;
          that.isPaidui = false;
          clearInterval(that.interval);
        })
      } else {
        var data = that.commonData();
        this.init(data.key, data.authToken);
      }
    },
  },
  destroyed() {
    // 销毁监听
    // this.close();
  },
};
</script>
<style lang='scss'>
  .im_fotter_head{
    .avatar-uploader .el-upload{
      width:28px;
      height: 28px;
      border: none;
    }
  }
</style>
<style scoped lang="scss">
   @import "./IndexBody.scss";
</style>